/**
 * @公司:公约树
 * @位置:苏州
 * @Classname AnimeCore
 * @Date 2022-05-31 下午 09:27
 * @Created by hanWanLu
 * @auther 中文:韩万路
 */


package com.animeJava.core;

import com.animeJava.enumData.VersionEnum;
import com.animeJava.mode.PositionVarModel;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 动画核心功能
 */
public class AnimeCore {

    private PositionVarModel in;
    private PositionVarModel in1;

    private PositionVarModel add_1;
    private PositionVarModel to;
    private PositionVarModel to1;

    private EasingData easingData;
    private double toTime;

    private VersionEnum version = VersionEnum.V_1;    //版本控制
    /**
     * 时间动画中心
     * @param easingData    曲线数据
     * @param toTime        到的时间  不可大于1和小于零
     * @return  返回当前算出位置的大小
     */
    public Map<String,PositionVarModel> core(EasingData easingData , double toTime ) {
        if(!(toTime >= 0 && toTime <= 1)){
            new Exception("范围不正确请检查:"+toTime);
        }

        this.easingData = easingData;

        in = new PositionVarModel(easingData.getInX(),easingData.getInY());
        in1 = new PositionVarModel(easingData.getX1(),easingData.getY1());
        if(easingData.getX1_1() != null && easingData.getY1_1() != null ){
            add_1 = new PositionVarModel(easingData.getX1_1(),easingData.getY1_1());
            version = VersionEnum.V_2;
        }

        to = new PositionVarModel(easingData.getX2(),easingData.getY2());
        to1 = new PositionVarModel(easingData.getToX(),easingData.getToY());

        this.toTime = new BigDecimal(toTime).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();

        switch (version){
            case V_2:
                return preloadedParseV2();
            case V_1:
            default:
                return preloadedParse();
        }
    }

    /**
     * 二分算法 不需要递归
     * @return
     */
    private Map<String , PositionVarModel> preloadedParse(){
        //计算当前被萨尔曲线
        double  thisStep    =   0   ;
        double  min         =   0   ;
        double  max         =   1   ;
        while(true){
            thisStep = (max - min) / 2 + min;

            //第三维
            PositionVarModel inChildren = in.toComputed(in1, thisStep); //从起点到起点结束
            PositionVarModel toChildren = to.toComputed(to1, thisStep);//从终点开始 到终点结束
            PositionVarModel ceChildren = in1.toComputed(to, thisStep); //从起点结束 到终点开始

            //转第二维
            PositionVarModel in1Client = inChildren.toComputed(ceChildren, thisStep);   //从起点中间到 三维的第二维度之中
            PositionVarModel to1Client = ceChildren.toComputed(toChildren, thisStep);   //从三维的第二维度到第三维度

            //转第一维度
            PositionVarModel finalPosition = in1Client.toComputed(to1Client, thisStep); //压缩维度

            //判断当前的X时间轴在什么地方来细分所到的位置
            double x = new BigDecimal(finalPosition.getX()).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();

            if ( x == this.toTime ){
                Map<String, PositionVarModel> stringPositionVarModelMap = new HashMap<String, PositionVarModel>(){{
                    put("inChildren",inChildren);
                    put("toChildren",toChildren);
                    put("finalPosition",finalPosition);
                }};
                return stringPositionVarModelMap;    //计算完毕递归
            }else{
                if( x > this.toTime ){
                    max = thisStep;
                }else if(x < this.toTime){
                    min = thisStep;
                }
            }
        }
    }
    /**
     * 二分算法 不需要递归
     * @return
     */
    private Map<String , PositionVarModel> preloadedParseV2(){
        //计算当前被萨尔曲线
        double  thisStep    =   0   ;
        double  min         =   0   ;
        double  max         =   1   ;
        while(true){
            thisStep = (max - min) / 2 + min;

            //判断是否启用第四维度
            PositionVarModel inFinal = in.toComputed(in1, thisStep); //从起点到起点结束
            PositionVarModel toFinal = to.toComputed(to1, thisStep);//从终点开始 到终点结束
            PositionVarModel ceFinal = in1.toComputed(add_1, thisStep); //从起点结束 到终点开始
            PositionVarModel ce2Final = add_1.toComputed(to1, thisStep); //从起点结束 到终点开始

            //第三维
            PositionVarModel inChildren = inFinal.toComputed(ceFinal, thisStep); //从起点到起点结束
            PositionVarModel toChildren = ce2Final.toComputed(toFinal, thisStep);//从终点开始 到终点结束
            PositionVarModel ceChildren = ceFinal.toComputed(ce2Final, thisStep); //从起点结束 到终点开始

            //转第二维
            PositionVarModel in1Client = inChildren.toComputed(ceChildren, thisStep);   //从起点中间到 三维的第二维度之中
            PositionVarModel to1Client = ceChildren.toComputed(toChildren, thisStep);   //从三维的第二维度到第三维度

            //转第一维度
            PositionVarModel finalPosition = in1Client.toComputed(to1Client, thisStep); //压缩维度

            //判断当前的X时间轴在什么地方来细分所到的位置
            double x = new BigDecimal(finalPosition.getX()).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();

            if ( x == this.toTime ){
                Map<String, PositionVarModel> stringPositionVarModelMap = new HashMap<String, PositionVarModel>(){{
                    put("inChildren",inChildren);
                    put("toChildren",toChildren);
                    put("finalPosition",finalPosition);
                    put("inFinal",inFinal);
                    put("toFinal",toFinal);
                    put("ceFinal",ceFinal);
                    put("ce2Final",ce2Final);
                }};
                return stringPositionVarModelMap;    //计算完毕递归
            }else{
                if( x > this.toTime ){
                    max = thisStep;
                }else if(x < this.toTime){
                    min = thisStep;
                }
            }
        }
    }

}
